package scuts.core.macros;

#if macro
import scuts.macro.Convert;
import haxe.macro.Compiler;
import scuts.macro.Check;
import scuts.macro.Extract;
import scuts.macro.Parse;
import scuts.macro.Print;
import scuts.macro.Make;
import haxe.macro.Context;
import haxe.macro.Expr;
using scuts.core.extensions.Options;
using scuts.core.Map;
using scuts.core.ReverseCopy;
class MakeStaxList {
  /*
   * returns
   * { 
   *   var l:List<BaseType> = new List();
   *   l.push(expr_1);
   *   ...
   *   l.push(expr_N);
   *   l;
   * }
   * 
   * usage: 
   *  [1,1.0].asList(Float) => List<Float>
   *  [[1,1],[2, 2.1]].asList("List<Float>") // should work recursive 
   */
  public static function asStaxList (arr:ExprRequire<Array<Dynamic>>, baseType:Expr, order:Expr, equal:Expr, hash:Expr, show:Expr) {
     // baseType must be const String for or a Type
    
    var arrDecl = Extract.extractArrayDeclValues(arr);

    if (arrDecl.isNone()) {
      Context.error("Argument arr must be const array", arr.pos);
    } else {
      var validBaseType = Check.isConstString(baseType) || Check.isType(baseType);
      if (validBaseType) {
        var values = arrDecl.value();
        values.reverse();
         var s = "{ var l:haxe.data.collections.List<$0> = haxe.data.collections.List.create($1, $2, $3, $4); l" 
              + arrDecl.value().mapWithIndex(function (v, i) return ".cons($" + (i + 5) + ")").join("")
         + ";}";
         
         var a:Array<Dynamic> = arrDecl.value().copy();
         a.unshift(show);
         a.unshift(hash);
         a.unshift(equal);
         a.unshift(order);
         a.unshift(baseType);
         trace(s);
         trace(a.length);
         var e = Parse.parse(s, a);
         trace(Print.exprStr(e));
         return e;
      } else {
        Context.error("Argument baseType must be a valid Type", arr.pos);
      }
      
    }
    
    return Make.mkEmptyBlock();
  }
}
#end